<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>幂等性与重复操作问题解决方案</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
        }
        .code-block {
            background: #1e293b;
            border-radius: 12px;
            overflow: hidden;
        }
        .code-header {
            background: #334155;
            padding: 8px 16px;
            font-size: 14px;
            color: #94a3b8;
        }
        pre {
            margin: 0;
            padding: 20px;
            overflow-x: auto;
        }
        code {
            font-family: 'Consolas', 'Monaco', monospace;
            color: #e2e8f0;
            font-size: 14px;
            line-height: 1.6;
        }
        .section-divider {
            height: 2px;
            background: linear-gradient(to right, transparent, #e5e7eb, transparent);
        }
        .number-circle {
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            border-radius: 50%;
            font-weight: bold;
        }
        .mermaid {
            display: flex;
            justify-content: center;
            margin: 2rem 0;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20">
        <div class="container mx-auto px-6">
            <div class="max-w-4xl mx-auto text-center">
                <h1 class="text-5xl font-bold mb-6 leading-tight">
                    <i class="fas fa-shield-alt mr-4"></i>幂等性与重复操作问题解决方案
                </h1>
                <p class="text-xl opacity-90 leading-relaxed">
                    通过综合运用客户端和服务器端策略，确保系统稳定性和数据一致性，打造高可靠性的分布式系统
                </p>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto px-6 py-12">
        <!-- Introduction Card -->
        <div class="max-w-5xl mx-auto mb-12">
            <div class="bg-white rounded-2xl shadow-lg p-8 card-hover">
                <div class="flex items-start">
                    <div class="mr-6">
                        <div class="w-16 h-16 bg-purple-100 rounded-full flex items-center justify-center">
                            <i class="fas fa-lightbulb text-purple-600 text-2xl"></i>
                        </div>
                    </div>
                    <div class="flex-1">
                        <h2 class="text-2xl font-bold text-gray-800 mb-4">核心理念</h2>
                        <p class="text-gray-600 leading-relaxed text-lg">
                            解决幂等性和重复操作问题需要综合考虑客户端和服务器端的处理策略。通过使用唯一标识符、数据库事务、分布式锁等方法，可以有效避免重复处理请求，确保系统的稳定性和数据一致性。在设计系统时，考虑到这些策略可以显著提升系统的鲁棒性和用户体验。
                        </p>
                    </div>
                </div>
            </div>
        </div>

        <!-- Concept Visualization -->
        <div class="max-w-5xl mx-auto mb-16">
            <div class="bg-white rounded-2xl shadow-lg p-8">
                <h3 class="text-2xl font-bold text-gray-800 mb-6 text-center">
                    <i class="fas fa-project-diagram mr-3 text-purple-600"></i>幂等性解决方案架构
                </h3>
                <div class="mermaid">
                    graph TD
                        A[客户端请求] --> B{请求去重}
                        B -->|新请求| C[唯一标识符检查]
                        B -->|重复请求| D[返回缓存结果]
                        C --> E{分布式锁}
                        E -->|获取锁成功| F[执行业务逻辑]
                        E -->|获取锁失败| G[等待或拒绝]
                        F --> H[数据库事务]
                        H --> I[更新状态]
                        I --> J[缓存结果]
                        J --> K[返回响应]
                        
                        style A fill:#f9f,stroke:#333,stroke-width:2px
                        style K fill:#9f9,stroke:#333,stroke-width:2px
                        style E fill:#ff9,stroke:#333,stroke-width:2px
                </div>
            </div>
        </div>

        <!-- Section 1: 幂等性设计 -->
        <section class="max-w-5xl mx-auto mb-16">
            <div class="flex items-center mb-8">
                <div class="number-circle mr-4">1</div>
                <h2 class="text-3xl font-bold text-gray-800">幂等性设计</h2>
            </div>
            
            <div class="bg-white rounded-2xl shadow-lg p-8 mb-8">
                <p class="text-lg text-gray-700 mb-6">
                    <strong>幂等性</strong>是指无论同一操作执行多少次，结果都是相同的。为了实现幂等性，可以采取以下措施：
                </p>

                <!-- 1.1 使用唯一标识符 -->
                <div class="mb-10">
                    <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                        <i class="fas fa-fingerprint text-purple-600 mr-3"></i>
                        1.1 使用唯一标识符（ID）
                    </h3>
                    <p class="text-gray-600 mb-6">
                        每个请求附带一个唯一标识符，如订单号、请求 ID 或事务 ID。服务器端在处理请求时，首先检查这个 ID 是否已经处理过，如果处理过，则返回之前的结果，避免重复处理。
                    </p>
                    
                    <div class="code-block">
                        <div class="code-header">
                            <i class="fab fa-java mr-2"></i>IdempotentService.java
                        </div>
                        <pre><code>public class IdempotentService {

    private Set&lt;String&gt; processedIds = new HashSet&lt;&gt;();

    public synchronized String processRequest(String requestId) {
        if (processedIds.contains(requestId)) {
            return "Request already processed.";
        }
        processedIds.add(requestId);
        // 处理业务逻辑
        return "Request processed successfully.";
    }
}</code></pre>
                    </div>
                </div>

                <!-- 1.2 使用数据库事务 -->
                <div class="mb-10">
                    <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                        <i class="fas fa-database text-purple-600 mr-3"></i>
                        1.2 使用数据库事务
                    </h3>
                    <p class="text-gray-600 mb-6">
                        数据库操作通常支持事务机制。通过将操作封装在事务中，可以确保操作的原子性，避免因重复请求导致的数据不一致。
                    </p>
                    
                    <div class="code-block">
                        <div class="code-header">
                            <i class="fab fa-java mr-2"></i>TransactionalService.java
                        </div>
                        <pre><code>@Transactional
public void performDatabaseOperation() {
    // 数据库操作
}</code></pre>
                    </div>
                </div>

                <!-- 1.3 使用分布式锁 -->
                <div class="mb-6">
                    <h3 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                        <i class="fas fa-lock text-purple-600 mr-3"></i>
                        1.3 使用分布式锁
                    </h3>
                    <p class="text-gray-600 mb-6">
                        在分布式环境中，可以使用分布式锁（如 Redis 的分布式锁）来防止同一操作被多次执行。分布式锁确保在同一时间只有一个请求能够执行某个操作。
                    </p>
                    
                    <div class="code-block">
                        <div class="code-header">
                            <i class="fab fa-java mr-2"></i>DistributedLockService.java
                        </div>
                        <pre><code>public class DistributedLockService {

    private final RedisTemplate&lt;String, String&gt; redisTemplate;

    public void performOperationWithLock(String lockKey) {
        Boolean acquired = redisTemplate.opsForValue()
            .setIfAbsent(lockKey, "locked", 5, TimeUnit.MINUTES);
        if (Boolean.TRUE.equals(acquired)) {
            try {
                // 执行操作
            } finally {
                redisTemplate.delete(lockKey);
            }
        } else {
            // 锁未获取，操作正在进行中
        }
    }
}</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <div class="section-divider max-w-5xl mx-auto mb-16"></div>

        <!-- Section 2: 防止重复提交 -->
        <section class="max-w-5xl mx-auto mb-16">
            <div class="flex items-center mb-8">
                <div class="number-circle mr-4">2</div>
                <h2 class="text-3xl font-bold text-gray-800">防止重复提交</h2>
            </div>

            <div class="grid md:grid-cols-2 gap-8">
                <!-- 客户端防重 -->
                <div class="bg-white rounded-2xl shadow-lg p-8 card-hover">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 bg-blue-100 rounded-full flex items-center justify-center mr-4">
                            <i class="fas fa-desktop text-blue-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold text-gray-800">2.1 客户端防重</h3>
                    </div>
                    <p class="text-gray-600">
                        在客户端（如浏览器）中，可以禁用按钮点击多次，或者在点击后禁用按钮，防止用户重复提交请求。
                    </p>
                </div>

                <!-- 后端去重 -->
                <div class="bg-white rounded-2xl shadow-lg p-8 card-hover">
                    <div class="flex items-center mb-4">
                        <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mr-4">
                            <i class="fas fa-server text-green-600 text-xl"></i>
                        </div>
                        <h3 class="text-xl font-semibold text-gray-800">2.2 后端去重</h3>
                    </div>
                    <p class="text-gray-600">
                        后端系统可以通过数据库或缓存系统来记录请求，防止相同请求被重复处理。
                    </p>
                </div>
            </div>

            <div class="bg-white rounded-2xl shadow-lg p-8 mt-8">
                <div class="code-block">
                    <div class="code-header">
                        <i class="fab fa-java mr-2"></i>RequestDeduplicationService.java
                    </div>
                    <pre><code>public class RequestDeduplicationService {

    private final Cache&lt;String, Boolean&gt; cache = CacheBuilder.newBuilder()
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();

    public boolean processRequest(String requestId) {
        if (cache.getIfPresent(requestId) != null) {
            return false; // 请求已处理
        }
        cache.put(requestId, true);
        // 处理请求
        return true; // 请求处理成功
    }
}</code></pre>
                </div>
            </div>
        </section>

        <div class="section-divider max-w-5xl mx-auto mb-16"></div>

        <!-- Section 3: 业务逻辑中的幂等性 -->
        <section class="max-w-5xl mx-auto mb-16">
            <div class="flex items-center mb-8">
                <div class="number-circle mr-4">3</div>
                <h2 class="text-3xl font-bold text-gray-800">业务逻辑中的幂等性</h2>
            </div>

            <div class="grid md: